use crate::error::{TauriResult, CommandResponse};
use crate::types::{GraphData, GraphMetadata, FileChange, GraphQuery, QueryResult};
use crate::services::codegraph::CodeGraphService;
use crate::services::progress::PROGRESS_MANAGER;
use tauri::command;

/// 初始化 CodeGraph
#[command]
pub async fn initialize_codegraph(workspace: String) -> TauriResult<CommandResponse<String>> {
    log::info!("Initializing CodeGraph for workspace: {}", workspace);
    
    // 创建异步操作
    let operation_id = PROGRESS_MANAGER.create_operation("initialize_codegraph".to_string());
    
    // 报告初始进度
    let _ = PROGRESS_MANAGER.update_progress(&operation_id, 0, 100, "开始初始化代码图谱".to_string());
    
    match CodeGraphService::initialize(&workspace, &operation_id).await {
        Ok(graph_id) => {
            let _ = PROGRESS_MANAGER.complete_operation(&operation_id, serde_json::to_value(&graph_id).unwrap());
            log::info!("CodeGraph initialized successfully: {}", graph_id);
            Ok(CommandResponse::success(graph_id))
        }
        Err(e) => {
            let _ = PROGRESS_MANAGER.fail_operation(&operation_id, e.to_string());
            log::error!("Failed to initialize CodeGraph: {}", e);
            Ok(CommandResponse::error(format!("初始化代码图谱失败: {}", e)))
        }
    }
}

/// 获取图谱数据
#[command]
pub async fn get_graph_data(graph_id: String) -> TauriResult<CommandResponse<GraphData>> {
    log::debug!("Getting graph data for: {}", graph_id);
    
    match CodeGraphService::get_graph_data(&graph_id).await {
        Ok(graph_data) => {
            log::debug!("Graph data retrieved: {} nodes, {} edges", 
                       graph_data.nodes.len(), graph_data.edges.len());
            Ok(CommandResponse::success(graph_data))
        }
        Err(e) => {
            log::error!("Failed to get graph data: {}", e);
            Ok(CommandResponse::error(format!("获取图谱数据失败: {}", e)))
        }
    }
}

/// 增量更新图谱
#[command]
pub async fn update_graph_incremental(changes: Vec<FileChange>) -> TauriResult<CommandResponse<String>> {
    log::info!("Updating graph incrementally with {} changes", changes.len());
    
    if changes.is_empty() {
        return Ok(CommandResponse::success("无变更需要处理".to_string()));
    }
    
    // 创建异步操作
    let operation_id = PROGRESS_MANAGER.create_operation("update_graph_incremental".to_string());
    
    // 报告初始进度
    let _ = PROGRESS_MANAGER.update_progress(&operation_id, 0, changes.len() as u64, "开始增量更新".to_string());
    
    match CodeGraphService::update_incremental(changes, &operation_id).await {
        Ok(update_result) => {
            let _ = PROGRESS_MANAGER.complete_operation(&operation_id, serde_json::to_value(&update_result).unwrap());
            log::info!("Graph updated incrementally: {}", update_result);
            Ok(CommandResponse::success(update_result))
        }
        Err(e) => {
            let _ = PROGRESS_MANAGER.fail_operation(&operation_id, e.to_string());
            log::error!("Failed to update graph incrementally: {}", e);
            Ok(CommandResponse::error(format!("增量更新失败: {}", e)))
        }
    }
}

/// 查询图谱
#[command]
pub async fn query_graph(query: GraphQuery) -> TauriResult<CommandResponse<QueryResult>> {
    log::debug!("Querying graph with query: {:?}", query);
    
    match CodeGraphService::query_graph(query).await {
        Ok(result) => {
            log::debug!("Query completed: {} results", result.nodes.len());
            Ok(CommandResponse::success(result))
        }
        Err(e) => {
            log::error!("Failed to query graph: {}", e);
            Ok(CommandResponse::error(format!("查询图谱失败: {}", e)))
        }
    }
}

/// 获取图谱统计信息
#[command]
pub async fn get_graph_stats(graph_id: String) -> TauriResult<CommandResponse<GraphMetadata>> {
    log::debug!("Getting graph stats for: {}", graph_id);
    
    match CodeGraphService::get_graph_stats(&graph_id).await {
        Ok(stats) => {
            log::debug!("Graph stats retrieved: {} nodes, {} edges", 
                       stats.node_count, stats.edge_count);
            Ok(CommandResponse::success(stats))
        }
        Err(e) => {
            log::error!("Failed to get graph stats: {}", e);
            Ok(CommandResponse::error(format!("获取图谱统计失败: {}", e)))
        }
    }
}

/// 导出图谱数据
#[command]
pub async fn export_graph(graph_id: String, format: String, output_path: String) -> TauriResult<CommandResponse<String>> {
    log::info!("Exporting graph {} to {} format at {}", graph_id, format, output_path);
    
    // 创建异步操作
    let operation_id = PROGRESS_MANAGER.create_operation("export_graph".to_string());
    
    // 报告初始进度
    let _ = PROGRESS_MANAGER.update_progress(&operation_id, 0, 100, "开始导出图谱".to_string());
    
    match CodeGraphService::export_graph(&graph_id, &format, &output_path, &operation_id).await {
        Ok(export_path) => {
            let _ = PROGRESS_MANAGER.complete_operation(&operation_id, serde_json::to_value(&export_path).unwrap());
            log::info!("Graph exported successfully to: {}", export_path);
            Ok(CommandResponse::success(export_path))
        }
        Err(e) => {
            let _ = PROGRESS_MANAGER.fail_operation(&operation_id, e.to_string());
            log::error!("Failed to export graph: {}", e);
            Ok(CommandResponse::error(format!("导出图谱失败: {}", e)))
        }
    }
}

/// 清理图谱缓存
#[command]
pub async fn cleanup_graph_cache() -> TauriResult<CommandResponse<String>> {
    log::info!("Cleaning up graph cache");
    
    match CodeGraphService::cleanup_cache().await {
        Ok(cleanup_result) => {
            log::info!("Cache cleanup completed: {}", cleanup_result);
            Ok(CommandResponse::success(cleanup_result))
        }
        Err(e) => {
            log::error!("Failed to cleanup cache: {}", e);
            Ok(CommandResponse::error(format!("清理缓存失败: {}", e)))
        }
    }
}

/// 重建图谱
#[command]
pub async fn rebuild_graph(workspace: String) -> TauriResult<CommandResponse<String>> {
    log::info!("Rebuilding graph for workspace: {}", workspace);
    
    // 创建异步操作
    let operation_id = PROGRESS_MANAGER.create_operation("rebuild_graph".to_string());
    
    // 报告初始进度
    let _ = PROGRESS_MANAGER.update_progress(&operation_id, 0, 100, "开始重建图谱".to_string());
    
    match CodeGraphService::rebuild(&workspace, &operation_id).await {
        Ok(graph_id) => {
            let _ = PROGRESS_MANAGER.complete_operation(&operation_id, serde_json::to_value(&graph_id).unwrap());
            log::info!("Graph rebuilt successfully: {}", graph_id);
            Ok(CommandResponse::success(graph_id))
        }
        Err(e) => {
            let _ = PROGRESS_MANAGER.fail_operation(&operation_id, e.to_string());
            log::error!("Failed to rebuild graph: {}", e);
            Ok(CommandResponse::error(format!("重建图谱失败: {}", e)))
        }
    }
}

/// 获取图谱健康状态
#[command]
pub async fn get_graph_health(graph_id: String) -> TauriResult<CommandResponse<serde_json::Value>> {
    log::debug!("Getting graph health for: {}", graph_id);
    
    match CodeGraphService::get_health_status(&graph_id).await {
        Ok(health) => {
            log::debug!("Graph health retrieved");
            Ok(CommandResponse::success(health))
        }
        Err(e) => {
            log::error!("Failed to get graph health: {}", e);
            Ok(CommandResponse::error(format!("获取图谱健康状态失败: {}", e)))
        }
    }
}
